package com.example.dragcontentviewdemo.helper;

import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import android.view.ViewGroup.OnHierarchyChangeListener;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.dragcontentviewdemo.R;
import com.example.dragcontentviewdemo.helper.internal.AttachInfo;
import com.example.dragcontentviewdemo.helper.internal.touchhandler.TouchHandler;
import com.example.dragcontentviewdemo.helper.internal.view.WrapperFrameLayout;
import com.example.dragcontentviewdemo.helper.api.DraggableActivityGestureListener;

import java.util.Objects;

/**
 * 通过该控制器来配置activity为手指拖动activity，控制器通过静态方法obtain创建
 */
public class DraggableActivityController {

    private static final int CONSTANT_MY_LAYOUT_VIEW_TAG = 12314;

    private AttachInfo mAttachInfo = null;
    private Activity mActivity = null;
    private View.OnTouchListener mWrapperViewOnTouchListener;
    private WrapperFrameLayout mWrapperView;
    private boolean mWrapperViewIsRemoved = false;

    /**
     * 传入需要控制的activity，返回一个控制器,控制器创建后即为配置完成，默认开启手指拖动
     * @param activity
     * @return
     */
    static public DraggableActivityController obtain(Activity activity) {
        DraggableActivityController controller = new DraggableActivityController(activity, null);
        controller.configure();
        return controller;
    }

    static public DraggableActivityController obtain(Activity activity, DraggableActivityGestureListener callback) {
        DraggableActivityController controller = new DraggableActivityController(activity, callback);
        controller.configure();
        return controller;
    }

    /**
     * 手指拖动过程中需要分发出去的事件通过callback传递，这里设置callback
     * @param callback
     */
    public void setCallback(DraggableActivityGestureListener callback) {
        mAttachInfo.callback = callback;
    }

    public void setVelocityXThreshold(float velocityXThreshold) {
        mAttachInfo.mVelocityXThreshold = velocityXThreshold;
    }

    /**
     * 设置禁用或者启用手指拖动
     * @param flag
     */
    public void setDraggable(boolean flag){
        mAttachInfo.mIntercept = flag;

    }

    /**
     * 设置拦截触摸事件的视图X范围
     *
     * @param start 0...end
     * @param end   start...1
     */
    public void setInterceptTouchEventRange(float start, float end) {
        start = Math.max(0.f, start);
        end = Math.min(1.f, Math.max(start, end));

        mAttachInfo.mXLowerBound = start;
        mAttachInfo.mXUpperBound = end;

    }

    public void resetPosition(){
        mAttachInfo.resetState();
    }

    public void destroy(){
        mWrapperView.setOnTouchListener(null);
        mWrapperViewOnTouchListener = null;
        mAttachInfo = null;
        mActivity = null;
    }

    private DraggableActivityController(Activity activity, DraggableActivityGestureListener callback) {
        mActivity = activity;
        mAttachInfo = new AttachInfo(callback);
    }

    private void configure() {
        /*
        配置过程：
        1. 调整decorView的现有子view
        2. 添加视图结构监听器应对后续对decorView的addView操作
         */
        ViewGroup decorView = (ViewGroup) mActivity.getWindow().getDecorView();
        wrapperDecorateProcess(decorView);

        decorView.setOnHierarchyChangeListener(new OnHierarchyChangeListener() {
            @Override
            public void onChildViewAdded(View parent, View child) {
                if (!mWrapperViewIsRemoved && !Objects.equals(child, mWrapperView)) {
                    mWrapperView.addView(child);
                }
            }

            @Override
            public void onChildViewRemoved(View parent, View child) {
                if (Objects.equals(child, mWrapperView)) {
                    mWrapperViewIsRemoved = true;
                }
            }
        });
    }

    // 将decorView目前的子View都添加到controller所控制的WrapperFrameLayout
    private void wrapperDecorateProcess(ViewGroup decorView ){
        final View[] children = stashViews(decorView);
        mWrapperView = reDecorateViewByWrapper(decorView, mActivity.getLayoutInflater(), WrapperFrameLayout.class, R.layout.inner_root);
        mWrapperView.attach(mAttachInfo);

        FrameLayout frameLayout = (FrameLayout) mActivity.getLayoutInflater().inflate(R.layout.frame_layout, mWrapperView,false);
        mWrapperView.addView(frameLayout);

        // 再遍历把view插回来
        for (int i = 0; i < children.length; i++) {
            frameLayout.addView(children[i]);
        }

        mWrapperViewOnTouchListener = new TouchHandler(mAttachInfo);

        // 这里添加一个走完子View后还没有被消费的事件的处理器
        mWrapperView.setOnTouchListener(mWrapperViewOnTouchListener);

        //设置背景的操作不应该这里来做 //TODO　删除这部分代码；
        Drawable bg = new CustomBackgroundDrawable(220 ); //maho value to be changed
        decorView.setBackground(bg);
    }

    private View[] stashViews(ViewGroup group){
        final int count = group.getChildCount();
        final View[] children = new View[count];
        for (int i = 0; i < count; i++) {
            children[i] = group.getChildAt(i);
        }
        group.removeAllViewsInLayout();
        return children;
    }

    private <V extends ViewGroup> V reDecorateViewByWrapper(ViewGroup decor, LayoutInflater inflater, Class<V> wrapperClass, int res_layout_id){
        //外层View用于接收事件，内层ViewGroup用来管理子View的统一移动
        V wrapper = wrapperClass.cast( inflater.inflate(res_layout_id, decor, false) );
        wrapper.setTag(CONSTANT_MY_LAYOUT_VIEW_TAG);
        decor.addView(wrapper);
        return wrapper;
    }

    private static final class ViewHolder {
        private WrapperFrameLayout wrapperView;
        private ViewGroup decorView;
    }


}


